const fs = require('fs-extra');
const path = require('path');

/**
 * Tree 格式生成器
 * 负责生成格式化的分析报告
 * @class TreeGenerator
 */
class TreeGenerator {
  constructor() {
    this.maxPathLength = 80; // 最长路径长度，超出则换行显示
  }

  /**
   * 生成分析报告
   * @param {Object} analysisData - 分析数据
   * @param {Object} options - 生成选项
   * @returns {string} 生成的报告内容
   */
  generate(analysisData, options = {}) {
    const { directory, files, stats } = analysisData;

    // 生成头部信息
    const header = this.generateHeader(directory, stats);

    // 生成文件树
    const fileTree = this.generateFileTree(files, options);

    // 生成统计摘要
    const summary = this.generateSummary(stats);

    // 生成错误信息（如果有）
    const errors = this.generateErrors(stats.errors);

    // 筛选大文件
    const largeFiles = this.getLargeFiles(files);

    // 组合所有部分
    const report = [
      header,
      fileTree,
      largeFiles ? this.generateLargeFilesSection(largeFiles) : '',
      summary,
      errors
    ].filter(Boolean).join('\n\n');

    return report;
  }

  /**
   * 保存报告到文件
   * @param {string} content - 报告内容
   * @param {string} outputPath - 输出路径
   * @returns {Promise<void>}
   */
  async saveToFile(content, outputPath) {
    try {
      // 确保输出目录存在
      const dir = path.dirname(outputPath);
      await fs.ensureDir(dir);

      // 写入文件
      await fs.writeFile(outputPath, content, 'utf-8');
    } catch (error) {
      throw new Error(`保存报告失败: ${error.message}`);
    }
  }

  /**
   * 生成报告头部
   * @param {string} directory - 分析目录
   * @param {Object} stats - 统计信息
   * @returns {string} 头部内容
   */
  generateHeader(directory, stats) {
    const now = new Date();
    const formattedTime = now.toLocaleString('zh-CN', {
      year: 'numeric',
      month: '2-digit',
      day: '2-digit',
      hour: '2-digit',
      minute: '2-digit',
      second: '2-digit'
    });

    return `# Vue 项目分析报告

**扫描路径**: ${directory}
**生成时间**: ${formattedTime}
**统计概览**: 共 ${stats.totalFiles} 个 .vue 文件，总代码量 ${stats.totalLines} 行`;
  }

  /**
   * 生成文件树
   * @param {Array} files - 文件数组
   * @param {Object} options - 选项
   * @returns {string} 文件树内容
   */
  generateFileTree(files, options) {
    if (files.length === 0) {
      return '## 文件统计详情\n\n未找到任何 .vue 文件';
    }

    // 按目录分组
    const fileGroups = this.groupFilesByDirectory(files);

    // 生成可点击的文件列表（在代码块外，支持点击）
    const clickableList = this.generateClickableFileList(fileGroups);

    // 生成纯文本树结构（用于代码块展示）
    const plainTreeStructure = this.buildTreeStructure(fileGroups, { enableLinks: false });

    return `## 文件统计详情

### 文件树结构
${plainTreeStructure}`;
  }

  /**
   * 生成可点击的文件列表
   * @param {Object} fileGroups - 文件分组
   * @returns {string} 可点击文件列表
   */
  generateClickableFileList(fileGroups) {
    const lines = [];

    Object.entries(fileGroups).forEach(([dir, files]) => {
      if (dir === '.' && files.length > 0) {
        lines.push('**根目录文件:**');
        files.forEach(file => {
          lines.push(`- [${file.fileName}](${file.relativePath}) - 模板:${file.templateLines}行 脚本:${file.scriptLines}行 样式:${file.styleLines}行 总计:${file.totalLines}行`);
        });
        lines.push('');
      } else if (dir !== '.') {
        lines.push(`**${dir}/**`);
        files.forEach(file => {
          lines.push(`- [${file.fileName}](${file.relativePath}) - 模板:${file.templateLines}行 脚本:${file.scriptLines}行 样式:${file.styleLines}行 总计:${file.totalLines}行`);
        });
        lines.push('');
      }
    });

    return lines.join('\n');
  }

  /**
   * 按目录分组文件
   * @param {Array} files - 文件数组
   * @returns {Object} 分组后的文件
   */
  groupFilesByDirectory(files) {
    const groups = {};

    files.forEach(file => {
      // 规范化路径，移除开头的 ./
      let dir = file.directory || '.';
      if (dir.startsWith('./')) {
        dir = dir.substring(2);
      }
      if (dir === '') {
        dir = '.';
      }

      if (!groups[dir]) {
        groups[dir] = [];
      }
      groups[dir].push(file);
    });

    // 排序目录和文件
    const sortedGroups = {};
    Object.keys(groups).sort().forEach(dir => {
      groups[dir].sort((a, b) => a.fileName.localeCompare(b.fileName));
      sortedGroups[dir] = groups[dir];
    });

    return sortedGroups;
  }

  /**
   * 构建树结构
   * @param {Object} fileGroups - 文件分组
   * @returns {string} 树结构字符串
   */
  buildTreeStructure(fileGroups, options = {}) {
    const lines = [];
    const directories = Object.keys(fileGroups);
    const enableLinks = options.enableLinks !== false;

    // 处理根目录
    if (directories.length === 1 && directories[0] === '.') {
      files = fileGroups['.'];
      files.forEach((file, index) => {
        const isLast = index === files.length - 1;
        const connector = isLast ? '└─' : '├─';
        const prefix = '';
        const filePrefix = prefix + connector; // 移除多余的空格
        lines.push(this.formatFileLine(file, filePrefix + ' ', connector, true)); // 始终启用链接
      });
    } else {
      // 多个目录，生成树结构
      const tree = this.buildDirectoryTree(fileGroups);
      lines.push(...this.renderDirectoryTree(tree, '', true)); // 始终启用链接
    }

    return lines.join('\n');
  }

  /**
   * 构建目录树
   * @param {Object} fileGroups - 文件分组
   * @returns {Object} 目录树
   */
  buildDirectoryTree(fileGroups) {
    const tree = {};

    Object.entries(fileGroups).forEach(([dirPath, files]) => {
      // 跳过根目录的特殊处理
      if (dirPath === '.') {
        tree.__files = files;
        return;
      }

      const parts = dirPath.split('/').filter(Boolean);
      let current = tree;

      // 创建目录结构
      parts.forEach((part, index) => {
        if (!current[part]) {
          current[part] = { __type: 'directory', __files: [] };
        }
        current = current[part];
      });

      // 添加文件
      files.forEach(file => {
        current.__files.push(file);
      });
    });

    return tree;
  }

  /**
   * 渲染目录树
   * @param {Object} tree - 目录树
   * @param {string} prefix - 前缀
   * @param {boolean} enableLinks - 是否启用链接
   * @returns {Array} 渲染行数组
   */
  renderDirectoryTree(tree, prefix = '', enableLinks = true) {
    const lines = [];

    // 先处理根目录的文件
    if (tree.__files && tree.__files.length > 0) {
      tree.__files.forEach((file, index) => {
        const isLast = index === tree.__files.length - 1 && !Object.keys(tree).some(key => key !== '__files');
        const connector = isLast ? '└─' : '├─';
        lines.push(this.formatFileLine(file, prefix + connector + ' ', connector, enableLinks));
      });
    }

    // 获取所有目录键并排序
    const keys = Object.keys(tree)
      .filter(key => key !== '__type' && key !== '__files')
      .sort();

    keys.forEach((key, index) => {
      const isLast = index === keys.length - 1;
      const node = tree[key];
      const currentPrefix = prefix + (isLast ? '└─' : '├─') + '  ';
      const nextPrefix = prefix + (isLast ? '    ' : '│  ');

      // 添加目录行
      lines.push(`${currentPrefix}${key}/`);

      // 添加文件（如果有）
      if (node.__files && node.__files.length > 0) {
        node.__files.forEach((file, fileIndex) => {
          const fileIsLast = fileIndex === node.__files.length - 1;
          const fileConnector = fileIsLast ? '└─' : '├─';
          const filePrefix = nextPrefix + (fileIsLast ? '    ' : '│  ');
          lines.push(this.formatFileLine(file, filePrefix, fileConnector, enableLinks));
        });
      }

      // 递归处理子目录
      const subKeys = Object.keys(node).filter(key => key !== '__type' && key !== '__files');
      if (subKeys.length > 0) {
        const subTree = {};
        subKeys.forEach(subKey => {
          subTree[subKey] = node[subKey];
        });
        const subLines = this.renderDirectoryTree(subTree, nextPrefix, enableLinks);
        lines.push(...subLines);
      }
    });

    return lines;
  }

  /**
   * 格式化文件行
   * @param {Object} file - 文件信息
   * @param {string} prefix - 前缀
   * @param {string} connector - 连接符
   * @param {boolean} enableLinks - 是否启用链接
   * @returns {string} 格式化行
   */
  formatFileLine(file, prefix, connector, enableLinks = true) {
    const stats = `模板:${file.templateLines}行 脚本:${file.scriptLines}行 样式:${file.styleLines}行 总计:${file.totalLines}行`;

    let fileName;
    if (enableLinks) {
      // 创建可点击的文件链接 (适用于 VS Code、WebStorm 等编辑器)
      const fileLink = `[${file.fileName}](${file.relativePath})`;
      fileName = `${connector} ${fileLink}`;
    } else {
      // 纯文本文件名
      fileName = `${connector} ${file.fileName}`;
    }

    // 构建完整的行
    const separator = file.fileName.length < 30 ? ' '.repeat(35 - file.fileName.length) : ' ';
    const fullLine = fileName + separator + stats;

    return `${prefix}${fullLine}`;
  }

  /**
   * 生成统计摘要
   * @param {Object} stats - 统计信息
   * @returns {string} 摘要内容
   */
  generateSummary(stats) {
    if (stats.totalFiles === 0) return '';

    const lines = [
      '## 统计摘要',
      '',
      `- **文件总数**: ${stats.totalFiles} 个`,
      `- **代码总行数**: ${stats.totalLines} 行`,
      `- **最大文件**: ${stats.maxFile?.fileName || 'N/A'} (${stats.maxFile?.totalLines || 0} 行)`,
      `- **最小文件**: ${stats.minFile?.fileName || 'N/A'} (${stats.minFile?.totalLines || 0} 行)`,
      `- **平均行数**: ${stats.avgLines} 行`,
      ''
    ];

    // 分类统计
    lines.push('### 分类统计');
    lines.push(`- **模板代码**: ${stats.templateLines} 行 (平均 ${stats.avgTemplateLines} 行/文件)`);
    lines.push(`- **脚本代码**: ${stats.scriptLines} 行 (平均 ${stats.avgScriptLines} 行/文件)`);
    lines.push(`- **样式代码**: ${stats.styleLines} 行 (平均 ${stats.avgStyleLines} 行/文件)`);

    // 计算百分比
    if (stats.totalLines > 0) {
      const templatePercent = Math.round(stats.templateLines / stats.totalLines * 100);
      const scriptPercent = Math.round(stats.scriptLines / stats.totalLines * 100);
      const stylePercent = Math.round(stats.styleLines / stats.totalLines * 100);

      lines.push('');
      lines.push('### 代码分布');
      lines.push(`- **模板**: ${templatePercent}%`);
      lines.push(`- **脚本**: ${scriptPercent}%`);
      lines.push(`- **样式**: ${stylePercent}%`);
    }

    return lines.join('\n');
  }

  /**
   * 筛选大文件（总行数>500或任意一项>300行）
   * @param {Array} files - 文件数组
   * @returns {Array} 大文件数组
   */
  getLargeFiles(files) {
    return files.filter(file =>
      file.totalLines > 500 ||
      file.templateLines > 300 ||
      file.scriptLines > 300 ||
      file.styleLines > 300
    );
  }

  /**
   * 生成大文件章节
   * @param {Array} largeFiles - 大文件数组
   * @returns {string} 大文件章节内容
   */
  generateLargeFilesSection(largeFiles) {
    if (!largeFiles || largeFiles.length === 0) {
      return '';
    }

    const lines = [
      '## 大文件统计',
      '',
      '以下文件超过设定的阈值（总行数>500或任意一项>300行）：'
    ];

    largeFiles.forEach((file, index) => {
      const reasons = [];
      if (file.totalLines > 500) reasons.push(`总行数${file.totalLines}行`);
      if (file.templateLines > 300) reasons.push(`模板${file.templateLines}行`);
      if (file.scriptLines > 300) reasons.push(`脚本${file.scriptLines}行`);
      if (file.styleLines > 300) reasons.push(`样式${file.styleLines}行`);

      lines.push(`${index + 1}. [${file.fileName}](${file.relativePath})`);
      lines.push(`   - **阈值原因**: ${reasons.join(', ')}`);
      lines.push(`   - **模板**: ${file.templateLines}行, **脚本**: ${file.scriptLines}行, **样式**: ${file.styleLines}行`);
      lines.push(`   - **总计**: ${file.totalLines}行`);
      lines.push('');
    });

    lines.push(`**大文件统计**: 共 ${largeFiles.length} 个`);
    lines.push(`**超过阈值文件**: ${largeFiles.length} 个 (总代码量 ${largeFiles.reduce((sum, file) => sum + file.totalLines, 0)} 行)`);

    return lines.join('\n');
  }

  /**
   * 生成错误信息
   * @param {Array} errors - 错误数组
   * @returns {string} 错误信息
   */
  generateErrors(errors) {
    if (!errors || errors.length === 0) return '';

    const lines = [
      '## 错误信息',
      '',
      ...errors.map((error, index) => {
        return `${index + 1}. **${error.file}**: ${error.error}`;
      })
    ];

    return lines.join('\n');
  }
}

module.exports = TreeGenerator;